using Firestarter.DB.Schema.Logic;
using FireStarterModeller.BO;
using Habanero.BO;
using Habanero.Testability;
using NUnit.Framework;

namespace Firestarter.DB.Schema.Test.Logic
{
    [TestFixture]
    public class TestDBTypeConverter
    {
        [TestFixtureSetUp]
        public virtual void SetupFixture()
        {
            TestUtilsDBSchema.LoadClassDefs();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }
        
        private static string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }
        [Test]
        public void Test_Construct()
        {
            //---------------Set up test pack-------------------
            BusinessObjectCollection<TypeMapping> typeMappings = new BusinessObjectCollection<TypeMapping>();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            DBTypeConverter dbTypeConverter = new DBTypeConverter(typeMappings);
            //---------------Test Result -----------------------
            Assert.AreSame(typeMappings, dbTypeConverter.TypeMappings);
        }

        [Test]
        public void Test_Convert_WhenNoMappings_ShouldReturnSame()
        {
            //---------------Set up test pack-------------------
            const string myType = "VARCHAR";
            BusinessObjectCollection<TypeMapping> typeMappings = new BusinessObjectCollection<TypeMapping>();
            DBTypeConverter dbTypeConverter = new DBTypeConverter(typeMappings);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            string returnedType = dbTypeConverter.Convert(myType);
            //---------------Test Result -----------------------
            Assert.AreEqual(myType, returnedType);
        }

        [Test]
        public void Test_Convert_WhenMappingNotFound_ShouldReturnSame()
        {
            //---------------Set up test pack-------------------
            const string myType = "VARCHAR";
            BusinessObjectCollection<TypeMapping> typeMappings = new BusinessObjectCollection<TypeMapping>();
            typeMappings.Add(new TypeMapping { FromType = GetRandomString(), ToType = "aaa" });
            DBTypeConverter dbTypeConverter = new DBTypeConverter(typeMappings);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            string returnedType = dbTypeConverter.Convert(myType);
            //---------------Test Result -----------------------
            Assert.AreEqual(myType, returnedType);
        }

        [Test]
        public void Test_Convert_WhenMappingFound_ShouldReturnMapped()
        {
            //---------------Set up test pack-------------------
            const string myType = "VARCHAR";
            string expectedType = GetRandomString();
            BusinessObjectCollection<TypeMapping> typeMappings = new BusinessObjectCollection<TypeMapping>();
            typeMappings.Add(new TypeMapping { FromType = myType, ToType = expectedType });
            DBTypeConverter dbTypeConverter = new DBTypeConverter(typeMappings);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, typeMappings.Count);
            //---------------Execute Test ----------------------
            string returnedType = dbTypeConverter.Convert(myType);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedType, returnedType);
        }

        [Test]
        public void Test_Convert_WhenDifferentCaseMappingFound_ShouldReturnMapped()
        {
            //---------------Set up test pack-------------------
            const string myType = "VARCHAR";
            string myDifferentCaseType = myType.ToLower();
            string expectedType = GetRandomString();
            BusinessObjectCollection<TypeMapping> typeMappings = new BusinessObjectCollection<TypeMapping>();
            typeMappings.Add(new TypeMapping { FromType = myDifferentCaseType, ToType = expectedType });
            DBTypeConverter dbTypeConverter = new DBTypeConverter(typeMappings);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, typeMappings.Count);
            //---------------Execute Test ----------------------
            string returnedType = dbTypeConverter.Convert(myType);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedType, returnedType);
        }

        [Test]
        public void Test_DBDataTypeMapping_MySQL()
        {
            //---------------Set up test pack-------------------
            DBDataTypeMappingMySQL dataTypeMappingMySQL = new DBDataTypeMappingMySQL();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            BusinessObjectCollection<TypeMapping> typeMappings = dataTypeMappingMySQL.GetDefaultTypeMappings();
            //---------------Test Result -----------------------
            Assert.IsNotNull(typeMappings);
            Assert.IsTrue(typeMappings.Count > 0);
            TypeMapping firstTypeMapping = typeMappings[0];
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.FromType));
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.ToType));
        }
        [Test]
        public void Test_DBDataTypeMapping_SQLite()
        {
            //---------------Set up test pack-------------------
            IDBDataTypeMapping dataTypeMappingMySQL = new DBDataTypeMappingSQLite();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            BusinessObjectCollection<TypeMapping> typeMappings = dataTypeMappingMySQL.GetDefaultTypeMappings();
            //---------------Test Result -----------------------
            Assert.IsNotNull(typeMappings);
            Assert.IsTrue(typeMappings.Count > 0);
            TypeMapping firstTypeMapping = typeMappings[0];
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.FromType));
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.ToType));
        }

        [Test]
        public void Test_DBDataTypeMapping_SQLServer()
        {
            //---------------Set up test pack-------------------
            DBDataTypeMappingSQLServer dataTypeMappingSQLServer = new DBDataTypeMappingSQLServer();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            BusinessObjectCollection<TypeMapping> typeMappings = dataTypeMappingSQLServer.GetDefaultTypeMappings();
            //---------------Test Result -----------------------
            Assert.IsNotNull(typeMappings);
            Assert.IsTrue(typeMappings.Count > 0);
            TypeMapping firstTypeMapping = typeMappings[0];
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.FromType));
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.ToType));
        }

        [Test]
        public void Test_DBDataTypeMapping_Access()
        {
            //---------------Set up test pack-------------------
            DBDataTypeMappingAccess dataTypeMappingAccess = new DBDataTypeMappingAccess();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            BusinessObjectCollection<TypeMapping> typeMappings = dataTypeMappingAccess.GetDefaultTypeMappings();
            //---------------Test Result -----------------------
            Assert.IsNotNull(typeMappings);
            Assert.IsTrue(typeMappings.Count > 0);
            TypeMapping firstTypeMapping = typeMappings[0];
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.FromType));
            Assert.IsFalse(string.IsNullOrEmpty(firstTypeMapping.ToType));
        }
    }
}
